package com.spicdt.edge.protocol.door.demo.service;

import cn.hutool.core.util.StrUtil;
import cn.hutool.http.Header;
import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSON;
import com.spicdt.edge.protocol.door.demo.conf.DoorConf;
import com.spicdt.edge.protocol.door.demo.model.SrcResult;
import com.spicdt.edge.protocol.door.demo.utils.UrlConstants;
import com.spicdt.iedge.psdk.data.Response;
import com.spicdt.iedge.psdk.meta.StateEnum;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;

import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * 鑫业平台API接口服务类
 * 提供与鑫业平台进行HTTP通信的基础方法，包括POST/GET请求处理、参数封装、响应解析等功能
 */
@Slf4j
public class DoorApiBase {

    /**
     * 门禁系统配置信息
     * 包含主机地址、端口、超时设置等连接参数
     */
    protected DoorConf config;

    /**
     * 构造函数
     *
     * @param config 门禁系统配置对象
     */
    public DoorApiBase(DoorConf config) {
        this.config = config;
    }

    /**
     * 执行JSON格式的POST请求
     *
     * @param url 请求路径
     * @param paramMap 请求参数
     * @return HTTP响应结果
     */
    private String doPostJson(String url, Map<String, Object> paramMap) {
        return executeRequest(url, paramMap, RequestType.JSON);
    }

    /**
     * 执行表单格式的POST请求
     *
     * @param url 请求路径
     * @param paramMap 请求参数
     * @return HTTP响应结果
     */
    private String doPostForm(String url, Map<String, Object> paramMap) {
        return executeRequest(url, paramMap, RequestType.FORM);
    }

    /**
     * 执行GET请求
     *
     * @param url 请求路径
     * @param paramMap 请求参数
     * @return HTTP响应结果
     */
    private String doGet(String url, Map<String, Object> paramMap) {
        return executeRequest(url, paramMap, RequestType.GET);
    }

    /**
     * 通用请求执行方法
     *
     * @param url 请求路径
     * @param paramMap 请求参数
     * @param requestType 请求类型
     * @return HTTP响应结果
     */
    private String executeRequest(String url, Map<String, Object> paramMap, RequestType requestType) {

        try {
            String fullUrl = getProtocol(config) + config.getHost() + ":" + config.getPort() + url;
            String requestDescription = String.format("===========================请求鑫业平台接口：url=%s，请求参数：%s", fullUrl, JSONUtil.toJsonStr(paramMap));

            log.info(requestDescription);

            HttpRequest request = createRequest(fullUrl, paramMap, requestType);
            log.info("请求鑫业平台接口：token: {}", config.getCurrentToken());
            request.header("appToken",config.getCurrentToken());

//            log.info("========request========="+request);
//            log.info("========header========="+request.headers());
            HttpResponse execute = request.timeout(config.getTimeout()).execute();
            String body = execute.body();

            SrcResult srcResult = JSON.parseObject(body, SrcResult.class);
            if (UrlConstants.VALUE_TOKEN_DISABLE_CODE_020006.equals(srcResult.getCode())){
                getToken();
                request.header("appToken",config.getCurrentToken());
                body = request.timeout(config.getTimeout()).execute().body();
            }

            return body;
        } catch (Exception e) {
            log.error("HTTP请求执行失败：{}", e.getMessage(), e);
            return null;
        }
    }

    /**
     * 创建HTTP请求对象
     *
     * @param url 请求地址
     * @param paramMap 请求参数
     * @param requestType 请求类型
     * @return HttpRequest对象
     */
    private HttpRequest createRequest(String url, Map<String, Object> paramMap, RequestType requestType) {
        switch (requestType) {
            case JSON:
                return HttpRequest.post(url)
                    .header(Header.CONTENT_TYPE, "application/json")
                    .body(JSONUtil.toJsonStr(paramMap));
            case FORM:
                return HttpRequest.post(url).form(paramMap);
            case GET:
                return HttpRequest.get(url).form(paramMap);
            default:
                throw new IllegalArgumentException("Unsupported request type: " + requestType);
        }
    }

    /**
     * 执行POST JSON请求并解析结果
     *
     * @param url 请求路径
     * @param paramMap 请求参数
     * @return 响应结果对象
     */
    public Response doPostJsonResultBase(String url, Map<String, Object> paramMap) {
        return processResponse(doPostJson(url, paramMap));
    }



    /**
     * 处理HTTP响应结果
     *
     * @param result 原始响应结果
     * @return 标准化响应对象
     */
    private Response processResponse(String result) {
        if (StringUtils.isEmpty(result)) {
            log.warn("鑫业平台返回空结果");
            return Response.success("鑫业返回数据为空", null);
        }

        try {
            SrcResult srcResult = JSON.parseObject(result, SrcResult.class);
            if (UrlConstants.VALUE_SUCCESS_CODE_200.equals(srcResult.getCode())) {
                if (srcResult.getAppToken() != null){
                    srcResult.setBody(srcResult.getAppToken()+"}--}"+srcResult.getUnixTimestamp());
                }
                return Response.success("请求成功", srcResult.getBody());
            } else {
                log.warn("请求失败：code={}, message={}", srcResult.getCode(), srcResult.getMsg());
                return Response.fail(srcResult.getCode(), srcResult.getMsg(), null);
            }
        } catch (Exception e) {
            log.error("响应解析失败：{}", result, e);
            return Response.fail("PARSE_ERROR", "响应解析失败：" + e.getMessage(), null);
        }
    }

    private void getToken() {
        Response response = doPostJsonResultBase(UrlConstants.URL_XY_GET_TOKEN, JSONUtil.parseObj(config));
        if (response.isSuccess()) {
            Object data = response.getData();
            if (data != null) {
                String[] split = data.toString().split("}--}");
                config.setCurrentToken (split[0]);
                log.info("================token===============",config.getCurrentToken());
                config.setTokenExpirationTime (Long.valueOf(split[1])); ;
                log.info("Token 获取成功: {}", config.getCurrentToken());
                log.debug("Token 过期时间戳: {}", config.getTokenExpirationTime());
            } else {
                log.error("获取 Token 失败，响应数据为空");
                throw new RuntimeException("获取 Token 失败，响应数据为空");
            }
        }
    }

    /**
     * 获取协议类型（HTTP/HTTPS）
     *
     * @param config 配置对象
     * @return 协议类型字符串
     */
    private String getProtocol(DoorConf config) {
        // 实际生产环境应根据配置决定协议类型
        return "http://";
    }

    /**
     * 请求类型枚举
     */
    private enum RequestType {
        JSON, FORM, GET
    }
}